package com.note.app.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.houbb.sensitive.word.core.SensitiveWordHelper;
import com.note.app.dto.CommentCreateDTO;
import com.note.app.dto.CommentDTO;
import com.note.app.mapper.CommentMapper;
import com.note.app.mapper.NoteMapper;
import com.note.app.mapper.UserMapper;
import com.note.app.service.CommentService;
import com.note.common.domain.Comment;
import com.note.common.domain.Note;
import com.note.common.domain.User;
import com.note.common.exception.BusinessException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 评论服务实现
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class CommentServiceImpl implements CommentService {

    private final CommentMapper commentMapper;
    private final NoteMapper noteMapper;
    private final UserMapper userMapper;
    
    @Value("${sensitive.word.threshold:10}")
    private int sensitiveWordThreshold;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createComment(Long userId, CommentCreateDTO dto) {
        // 1. 检查笔记是否存在且用户有权限
        Note note = noteMapper.selectNoteWithPermission(dto.getNoteId(), userId);
        if (note == null) {
            throw new BusinessException("笔记不存在或无权限评论");
        }
        
        // 1.1 敏感词过滤
        String content = dto.getContent();
        if (content != null && !content.isEmpty()) {
            List<String> contentSensitiveWords = SensitiveWordHelper.findAll(content);
            
            if (contentSensitiveWords.size() > sensitiveWordThreshold) {
                throw new BusinessException("评论内容包含过多违规内容，请修改后重试，违规词数量：" + contentSensitiveWords.size());
            }
            
            // 替换敏感词
            if (!contentSensitiveWords.isEmpty()) {
                dto.setContent(SensitiveWordHelper.replace(content));
            }
        }
        
        // 2. 创建评论
        Comment comment = new Comment();
        comment.setNoteId(dto.getNoteId());
        comment.setUserId(userId);
        comment.setContent(dto.getContent());
        comment.setCreatedAt(LocalDateTime.now());
        comment.setUpdatedAt(LocalDateTime.now());
        
        // 3. 保存评论
        commentMapper.insert(comment);
        
        return comment.getId();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteComment(Long userId, Long commentId) {
        // 1. 检查评论是否存在
        Comment comment = commentMapper.selectById(commentId);
        if (comment == null) {
            throw new BusinessException("评论不存在");
        }
        
        // 2. 检查是否有权限删除（评论作者或笔记作者）
        if (!comment.getUserId().equals(userId)) {
            Note note = noteMapper.selectById(comment.getNoteId());
            if (note == null || !note.getUserId().equals(userId)) {
                throw new BusinessException("无权限删除该评论");
            }
        }
        
        // 3. 删除评论
        return commentMapper.deleteById(commentId) > 0;
    }

    @Override
    public Page<CommentDTO> getNoteComments(Long noteId, long current, long size) {
        // 1. 分页查询笔记评论
        Page<Comment> page = new Page<>(current, size);
        IPage<Comment> commentPage = commentMapper.selectPageByNoteId(page, noteId);
        
        // 2. 转换为DTO
        Page<CommentDTO> result = new Page<>(commentPage.getCurrent(), commentPage.getSize(), commentPage.getTotal());
        List<CommentDTO> records = commentPage.getRecords().stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
        
        // 3. 批量获取用户信息
        enrichUserInfo(records);
        
        result.setRecords(records);
        return result;
    }

    @Override
    public Page<CommentDTO> getUserComments(Long userId, long current, long size) {
        // 1. 分页查询用户评论
        Page<Comment> page = new Page<>(current, size);
        IPage<Comment> commentPage = commentMapper.selectPageByUserId(page, userId);
        
        // 2. 转换为DTO
        Page<CommentDTO> result = new Page<>(commentPage.getCurrent(), commentPage.getSize(), commentPage.getTotal());
        List<CommentDTO> records = commentPage.getRecords().stream()
                .map(this::convertToDTO)
                .collect(Collectors.toList());
        
        // 3. 批量获取用户信息和笔记信息
        enrichUserInfo(records);
        enrichNoteInfo(records);
        
        result.setRecords(records);
        return result;
    }

    @Override
    public int countCommentsByNoteId(Long noteId) {
        return commentMapper.countCommentsByNoteId(noteId);
    }
    
    /**
     * 将Comment实体转换为CommentDTO
     */
    private CommentDTO convertToDTO(Comment comment) {
        CommentDTO dto = new CommentDTO();
        BeanUtils.copyProperties(comment, dto);
        return dto;
    }
    
    /**
     * 批量填充用户信息
     */
    private void enrichUserInfo(List<CommentDTO> comments) {
        // 收集所有用户ID
        List<Long> userIds = comments.stream()
                .map(CommentDTO::getUserId)
                .distinct()
                .collect(Collectors.toList());
        
        if (!userIds.isEmpty()) {
            // 批量查询用户信息
            List<User> users = userMapper.selectBatchIds(userIds);
            Map<Long, User> userMap = users.stream()
                    .collect(Collectors.toMap(User::getId, user -> user));
            
            // 填充用户信息
            comments.forEach(comment -> {
                User user = userMap.get(comment.getUserId());
                if (user != null) {
                    comment.setUserName(user.getUsername());
                    comment.setUserAvatar(user.getAvatar());
                }
            });
        }
    }
    
    /**
     * 批量填充笔记信息
     */
    private void enrichNoteInfo(List<CommentDTO> comments) {
        // 收集所有笔记ID
        List<Long> noteIds = comments.stream()
                .map(CommentDTO::getNoteId)
                .distinct()
                .collect(Collectors.toList());
        
        if (!noteIds.isEmpty()) {
            // 批量查询笔记信息
            List<Note> notes = noteMapper.selectBatchIds(noteIds);
            Map<Long, Note> noteMap = notes.stream()
                    .collect(Collectors.toMap(Note::getId, note -> note));
            
            // 此处可以根据需要填充笔记相关信息
        }
    }
} 